package com.kalemao.library.utils.upload;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.FormBodyPart;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;

/**
 * HttpClien实现模拟表单post提交文件数据和字符参数，并支持大文件上传
 * 
 * @author dance
 *
 */
public class HttpClientUploadManager {

    public interface HttpClientUploadResponse {
        int SUCCESS = 1;
        int FAIL    = 0;
    }

    /**
     * 该方式是支持大文件上传的，如果用HttpURLConnection一般只能上传5M以内的，再大就OOM了
     *
     * @param mapParams
     *            字符参数的key和值封装好传入
     */
    public static PostResponse upload(String url, File file, String fileKey, HashMap<String, String> mapParams) {
        PostResponse postResult = null;
        HttpClient client = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
        client.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "utf-8");

        // httpPost.setHeader("Content-Type", "multipart/form-data;
        // boundary=9431149156168");

        try {
            MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

            Iterator<Entry<String, String>> iter = mapParams.entrySet().iterator();
            while (iter.hasNext()) {
                Entry<String, String> entry = (Entry<String, String>) iter.next();
                String key = entry.getKey();
                String value = entry.getValue();
                StringBody body = new StringBody(value, ContentType.MULTIPART_FORM_DATA);
                entity.addPart(key, body);
            }

            ContentBody contentBody = new FileBody(file);
            FormBodyPart formBodyPart = new FormBodyPart("file", contentBody);
            entity.addPart(formBodyPart);
            httpPost.setEntity(entity);
            HttpResponse response = client.execute(httpPost);

            if (response.getStatusLine().getStatusCode() == 201) { // 成功
                // 获取服务器返回值
                HttpEntity responseEntity = response.getEntity();
                InputStream input = responseEntity.getContent();

                try {
                    postResult = ParserByPULL.getResponse(input);
                } catch (Throwable e) {
                    e.printStackTrace();
                    return postResult;
                }

                // StringBuilder sb = new StringBuilder();
                // int s;
                // while ((s = input.read()) != -1) {
                // sb.append((char) s);
                // }
                return postResult;
            } else {
                return postResult;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return postResult;
        }
    }

    public static PostResponse upload(String url, byte[] mByte, HashMap<String, String> mapParams) {
        PostResponse postResult = null;
        HttpClient client = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
        client.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "utf-8");

        // httpPost.setHeader("Content-Type", "multipart/form-data;
        // boundary=9431149156168");

        try {
            MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

            Iterator<Entry<String, String>> iter = mapParams.entrySet().iterator();
            while (iter.hasNext()) {
                Entry<String, String> entry = (Entry<String, String>) iter.next();
                String key = entry.getKey();
                String value = entry.getValue();
                StringBody body = new StringBody(value, ContentType.MULTIPART_FORM_DATA);
                entity.addPart(key, body);
            }

            ContentBody contentBody = new ByteArrayBody(mByte, "android.jpg");
            FormBodyPart formBodyPart = new FormBodyPart("file", contentBody);
            entity.addPart(formBodyPart);
            httpPost.setEntity(entity);
            HttpResponse response = client.execute(httpPost);

            if (response.getStatusLine().getStatusCode() == 201) { // 成功
                // 获取服务器返回值
                HttpEntity responseEntity = response.getEntity();
                InputStream input = responseEntity.getContent();

                try {
                    postResult = ParserByPULL.getResponse(input);
                } catch (Throwable e) {
                    e.printStackTrace();
                    return postResult;
                }

                // StringBuilder sb = new StringBuilder();
                // int s;
                // while ((s = input.read()) != -1) {
                // sb.append((char) s);
                // }
                return postResult;
            } else {
                return postResult;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return postResult;
        }
    }

    public static byte[] getBytesFromFile(File f) {
        if (f == null) {
            return null;
        }
        try {
            FileInputStream stream = new FileInputStream(f);
            ByteArrayOutputStream out = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = stream.read(b)) != -1)
                out.write(b, 0, n);
            stream.close();
            out.close();
            return out.toByteArray();
        } catch (IOException e) {
        }
        return null;
    }
}
